﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using RefCodes.Services.RC.ReadOnly;
using DataModel;
using System.Collections.ObjectModel;
namespace RefCodes
{
    public partial class RefCodesComboBox : UserControl
    {
        public static Dictionary<int, ObservableCollection<RefCode>> Cache = new Dictionary<int, ObservableCollection<RefCode>>();
        public static Dictionary<int, ObservableCollection<RefCode>> CacheL2 = new Dictionary<int, ObservableCollection<RefCode>>();

        public RefCodesComboBox()
        {
            InitializeComponent();
            try
            {
                RC.GetRefCodesCompleted += new EventHandler<GetRefCodesCompletedEventArgs>(RC_GetRefCodesCompleted);
                RC.GetRefCodesL2Completed += new EventHandler<GetRefCodesL2CompletedEventArgs>(RC_GetRefCodesL2Completed);
            }
            catch (Exception)
            {
            }
            
        }


        void RC_GetRefCodesCompleted(object sender, GetRefCodesCompletedEventArgs e)
        {
            var L = Cache[(int)e.UserState];
            foreach (var item in e.Result)
            {
                L.Add(item);
            }
            //CBox.ItemsSource = e.Result;
            //RCs = e.Result;
            //UpdatedSelection();
        }
        void RC_GetRefCodesL2Completed(object sender, GetRefCodesL2CompletedEventArgs e)
        {
            var L = CacheL2[(int)e.UserState];
            foreach (var item in e.Result)
            {
                L.Add(item);
            }
            //CBox.ItemsSource = e.Result;
            //RCs = e.Result;
            //UpdatedSelection();
        }


        ObservableCollection<RefCode> RCs
        {
            get 
            {
                if (CBox.ItemsSource is ObservableCollection<RefCode>)
                {
                    return (ObservableCollection<RefCode>)CBox.ItemsSource; 
                }
                else
                {
                    return new ObservableCollection<RefCode>();
                }
            }
            set
            {
                CBox.ItemsSource = value;
                value.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(value_CollectionChanged);
                UpdatedSelection();
            }
        }

        void value_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            UpdatedSelection();
        }



        static object UpdateLocker = new object();
        void UpdateContents(int CodeType)
        {
            lock (UpdateLocker)
            {
                if (!Cache.ContainsKey(CodeType))
                {
                    Cache.Add(CodeType, new ObservableCollection<RefCode>());
                    RC.GetRefCodesAsync(CodeType, CodeType);
                }
                RCs = Cache[CodeType];
            }
        }
        void UpdateContentsL2(int RefCode)
        {
            lock (UpdateLocker)
            {
                if (!CacheL2.ContainsKey(RefCode))
                {
                    CacheL2.Add(RefCode, new ObservableCollection<RefCode>());
                    RC.GetRefCodesL2Async(RefCode, RefCode);
                }
                RCs = CacheL2[RefCode];
            }
        }



        public int CodeType
        {
            get { return (int)GetValue(CodeTypeProperty); }
            set { SetValue(CodeTypeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CodeType.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CodeTypeProperty =
            DependencyProperty.Register("CodeType", typeof(int), typeof(RefCodesComboBox), new PropertyMetadata(0, (DO,DE)=>
            {
                try
                {
                    var sender = ((RefCodesComboBox)DO);
                    sender.UpdateContents((int)DE.NewValue);
                }
                catch (Exception)
                {
                }

            }));



        public int L2RefCode
        {
            get { return (int)GetValue(L2RefCodeProperty); }
            set { SetValue(L2RefCodeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for L2RefCode.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty L2RefCodeProperty =
            DependencyProperty.Register("L2RefCode", typeof(int), typeof(RefCodesComboBox), new PropertyMetadata(0, (DO,DE)=>
            {
                try
                {
                    var sender = ((RefCodesComboBox)DO);
                    sender.UpdateContentsL2((int)DE.NewValue);
                }
                catch (Exception)
                {
                }

            }));

        



        void UpdatedSelection()
        {
            if (SelectedID.HasValue)
            {
                if (this.RCs.Any((RC) => RC.ID == SelectedID.Value))
                {
                    this.CBox.SelectedItem = this.RCs.First((RC) => RC.ID == SelectedID.Value);
                }                
            }
        }

        public int? SelectedID
        {
            get { return (int?)GetValue(SelectedIDProperty); }
            set { SetValue(SelectedIDProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedID.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedIDProperty =
            DependencyProperty.Register("SelectedID", typeof(int?), typeof(RefCodesComboBox), new PropertyMetadata(null, (DO, DE) => 
            {
                var sender = ((RefCodesComboBox)DO);
                sender.UpdatedSelection();
                //if (sender.RCs.Any((RC)=>RC.ID == (int)DE.NewValue))
                //{
                //    sender.CBox.SelectedItem = sender.RCs.First((RC) => RC.ID == (int)DE.NewValue);
                //}
            }));







        RefCodesReadOnlyServiceClient RC = ServiceConfig.NewRefCodesService();

        private void CBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CBox.SelectedItem != null)
            {
                SelectedID = ((RefCode)CBox.SelectedItem).ID;
            }
            else
            {
                SelectedID = null;
            }
        }
    }
}
